package com.webdrider.model.validators;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.common.model.abstracts.AbstractRequest;
import com.common.model.abstracts.AbstractValidator;
import com.common.security.abstracts.AbstractError;
import com.common.security.exceptions.ManagerException;
import com.google.appengine.api.datastore.Text;
import com.webdrider.manager.action.snippet.DomainManager;
import com.webdrider.manager.interfaces.IDomainManager;
import com.webdrider.model.action.snippet.Article;
import com.webdrider.model.action.snippet.Domain;
import com.webdrider.model.action.snippet.Tag;
import com.webdrider.model.requests.snippet.AddSnippetArticleRequest;
import com.webdrider.security.errors.SnippetError;

public class AddSnippetArticleValidator extends AbstractValidator {

	public static final int CONTENT_MIN_LENGTH = 1;
	public static final int CONTENT_MAX_LENGTH = 10000;
	public static final int TITLE_MIN_LENGTH = 1;
	public static final int TITLE_MAX_LENGTH = 250;
	
	private IDomainManager manager = new DomainManager();
	
	@Override
	public boolean validate(AbstractRequest abstractRequest) {
		AddSnippetArticleRequest request = null;
		
		if (abstractRequest instanceof AddSnippetArticleRequest) {
			request = (AddSnippetArticleRequest) abstractRequest;
		} else {
			error = new SnippetError(SnippetError.INVALID_REQUEST);
			return false;
		}
		
		try {
			Article article = request.getArticle();
			Domain domain = article.getDomain();
			Text text = article.getContent();
			String title = article.getTitle();
			List<Tag> tags = article.getTags();

			if (domain == null) {
				error = new SnippetError(SnippetError.NO_DOMAIN_PROVIDED);
				return false;
			}
			
			if (text == null) {
				error = new SnippetError(SnippetError.NO_CONTENT_PROVIDED);
				return false;
			}
			
			if (title == null) {
				error = new SnippetError(SnippetError.NO_TITLE_PROVIDED);
				return false;
			}
			
			int length = text.getValue().length();
			if (length < CONTENT_MIN_LENGTH || length > CONTENT_MAX_LENGTH) {
				error = new SnippetError(SnippetError.CONTENT_BAD_FORMAT);
				return false;
			}
			
			length = domain.getValue().length();
			if (length < AddSnippetDomainValidator.DOMAIN_MIN_LENGTH ||
					length > AddSnippetDomainValidator.DOMAIN_MAX_LENGTH) {
				error = new SnippetError(SnippetError.DOMAIN_BAD_FORMAT);
				return false;
			}
			
			if (!manager.exist(domain.getValue())) {
				error = new SnippetError(SnippetError.DOMAIN_NOT_FOUND);
				return false;
			}
			
			if (title.length() < TITLE_MIN_LENGTH || title.length() > TITLE_MAX_LENGTH) {
				error = new SnippetError(SnippetError.TITLE_BAD_FORMAT);
				return false;
			}
			
			Set<Tag> tagSet = new HashSet<Tag>();
			for (Tag tag : tags) {
				if (tag.getValue() == null || tag.getValue().length() < 1) {
					error = new SnippetError(SnippetError.TAG_BAD_FORMAT);
					return false;
				}
				if (tagSet.contains(tag)) {
					error = new SnippetError(SnippetError.DUPLICATE_TAG);
					return false;
				} else {
					tagSet.add(tag);
				}
			}
			
			return true;
		} catch (ManagerException e) {
			error = new SnippetError(AbstractError.DATABASE_ERROR);
			return false;
		}
	}

}